package lk.icta.core.entity;

import lk.icta.common.entity.BaseEntity;
import lk.icta.common.entity.Document;
import org.hibernate.annotations.IndexColumn;

import javax.persistence.*;
import java.io.Serializable;
import java.util.List;

/**
 * @author Mahesha Kalpanie
 */
@Entity
@Table(schema = "ELAND_RAIL")
@NamedQueries({
        @NamedQuery(
                name = "getAllAlienationMethodMetadataByLand",
                query = "SELECT lam FROM LandAssociation lam WHERE lam.land.id = :id AND lam.associationState<>1"
        ), @NamedQuery(
                name = "getAllNotApprovedDefineAlienationMetadata",
                query = "SELECT lam FROM LandAssociation lam WHERE  (lam.defineAMState<>1 OR lam.defineAMState IS NULL) AND lam.associationState=1  "
        ), @NamedQuery(
                name = "getAllNotApprovedDefineAlienationMetadataByUser",
                query = "SELECT lam FROM LandAssociation lam WHERE  (1 = :ignoreDS AND (lam.defineAMState<>1 OR lam.defineAMState IS NULL) " +
                        "AND (lam.associationState=1 OR lam.associationState=6 OR lam.associationState=4)  ) OR  (0 = :ignoreDS AND (lam.defineAMState<>1 OR lam.defineAMState IS NULL) AND (lam.associationState=1 OR lam.associationState=6 OR lam.associationState=4) AND lam.land.gnDivision.dsDivision IN (:DSList))  "
        ), @NamedQuery(
                name = "getAllNotApprovedDefineAlienationMetadataByGn",
                query = "SELECT lam FROM LandAssociation lam WHERE  (lam.defineAMState<>1 OR lam.defineAMState IS NULL) AND (lam.associationState=1 OR lam.associationState=6 OR lam.associationState=4) AND lam.land.gnDivision.id =:gnId "
        ),@NamedQuery(
                name = "getAllNotApprovedAssociationAlienationMethodMetadata",
                query = "SELECT lam FROM LandAssociation lam WHERE  lam.associationState<>1"
        ), @NamedQuery(
                name = "getAllNotApprovedAssociationAlienationMethodMetadataByUser",
                query = "SELECT lam FROM LandAssociation lam WHERE  (1 = :ignoreDS AND lam.associationState<>2 AND lam.associationState<>3 AND lam.associationState<>5 AND lam.associationState<>6 AND (lam.defineAMState =0 OR lam.defineAMState IS NULL)" +
                        ") OR  (0 = :ignoreDS AND lam.associationState<>2 AND lam.associationState<>3 AND lam.associationState<>5 AND lam.associationState<>6 AND (lam.defineAMState =0 OR lam.defineAMState IS NULL) AND lam.land.gnDivision.dsDivision IN (:DSList))  "
        ), @NamedQuery(
                name = "getAllNotApprovedAssociationAlienationMethodMetadataByGn",
                query = "SELECT lam FROM LandAssociation lam WHERE lam.associationState<>2 AND lam.associationState<>3 AND lam.associationState<>5 AND lam.associationState<>6 AND (lam.defineAMState =0 OR lam.defineAMState IS NULL) AND lam.land.gnDivision.id =:gnId  "
        ), @NamedQuery(
                name = "getAlienationMethodMetadataById",
                query = "SELECT lam FROM LandAssociation lam WHERE lam.id = :id"
        ),
        @NamedQuery(
                name = "getAllNotApprovedAlienationMethodMetadataByLand",
                query = "SELECT lam FROM LandAssociation lam WHERE lam.land.id = :id AND lam.associationState=2"
        ),
        @NamedQuery(
                name = "getAllNotApprovedDefineAlienationMethodMetadataByLand",
                query = "SELECT lam FROM LandAssociation lam WHERE lam.land.id = :id AND lam.defineAMState=2"
        ),
        @NamedQuery(
                name = "getAlienationMethodMetadataListByLand",
                query = "SELECT lam FROM LandAssociation lam WHERE lam.land.id = :id"
        ),
        @NamedQuery(
                name = "getAllAlienationMethodMetadataByAlienationMethod",
                query = "SELECT lam FROM LandAssociation lam WHERE lam.alienationMethod.id = :id"
        ),
        @NamedQuery(
                name = "getAllApprovedDefineAlienationMethodMetadataByUser",
                query = "SELECT lam FROM LandAssociation lam WHERE (1 = :ignoreDS AND lam.defineAMState=1) OR " +
                        "(0 = :ignoreDS AND lam.defineAMState=1 AND lam.land.gnDivision.dsDivision IN (:DSList))"
        ),
        @NamedQuery(
                name = "getAllApprovedDefineAlienationMethodMetadataByDs",
                query = "SELECT lam FROM LandAssociation lam WHERE lam.defineAMState=1 AND lam.land.gnDivision.dsDivision.id = :dsId"
        ) ,
        @NamedQuery(
                name = "getAllApprovedDefineAlienationMethodMetadataByDistrict",
                query = "SELECT lam FROM LandAssociation lam WHERE lam.defineAMState=1 AND lam.land.gnDivision.dsDivision.district.id = :districtId"
        ),
        @NamedQuery(
                name = "getAllApprovedDefineAlienationMethodMetadataByUserAndMethodId",
                query = "SELECT lam FROM LandAssociation lam WHERE (1 = :ignoreDS AND lam.defineAMState=1 AND lam.alienationMethod.id = :id) OR " +
                        "(0 = :ignoreDS AND lam.defineAMState=1 AND lam.alienationMethod.id = :id AND lam.land.gnDivision.dsDivision IN (:DSList))"
        )
})
public class LandAssociation extends BaseEntity {
    public enum AssociationState {
        REJECTED,   // 0                0 1 4      2 3 5 6
        APPROVED,   // 1   h
        DATA_ENTRY,  // 2
        DETAIL_LAND_DATA_ENTRY,  // 3  h
        DETAIL_LAND_DATA_ENTRY_APPROVED,  // 4
        KACHCHERY_DATA_ENTRY,  // 5         h
        KACHCHERY_APPROVED  // 6
    }

    public enum DefineAMState {
        REJECTED,   // 0
        APPROVED,   // 1
        DATA_ENTRY  // 2
    }

    @ManyToOne(optional = false, fetch = FetchType.EAGER)
    @JoinColumn
    private Land land;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn
    private AlienationMethod alienationMethod;

    @ManyToMany(fetch = FetchType.EAGER)
    //@IndexColumn(name = "INDEX_COL")
    @JoinTable(schema = "ELAND_RAIL")
    private List<AlienationMethod> alienationMethods;

    @Column(nullable = true)
    private String purpose;

    @Column(nullable = true)
    private AssociationState associationState;

    @Column(nullable = true)
    private DefineAMState defineAMState;

    @Column(nullable = true)
    private String associationComment;

    @Column(nullable = true)
    private String defineComment;

    @Transient
    private List<Document> documentList;

    public Land getLand() {
        return land;
    }

    public void setLand(Land land) {
        this.land = land;
    }

    public AlienationMethod getAlienationMethod() {
        return alienationMethod;
    }

    public void setAlienationMethod(AlienationMethod alienationMethod) {
        this.alienationMethod = alienationMethod;
    }

    public String getPurpose() {
        return purpose;
    }

    public void setPurpose(String purpose) {
        this.purpose = purpose;
    }

    public List<Document> getDocumentList() {
        return documentList;
    }

    public void setDocumentList(List<Document> documentList) {
        this.documentList = documentList;
    }

    public List<AlienationMethod> getAlienationMethods() {
        return alienationMethods;
    }

    public void setAlienationMethods(List<AlienationMethod> alienationMethods) {
        this.alienationMethods = alienationMethods;
    }

    public String getAssociationComment() {
        return associationComment;
    }

    public void setAssociationComment(String associationComment) {
        this.associationComment = associationComment;
    }

    public String getDefineComment() {
        return defineComment;
    }

    public void setDefineComment(String defineComment) {
        this.defineComment = defineComment;
    }

    public AssociationState getAssociationState() {
        return associationState;
    }

    public void setAssociationState(AssociationState associationState) {
        this.associationState = associationState;
    }

    public DefineAMState getDefineAMState() {
        return defineAMState;
    }

    public void setDefineAMState(DefineAMState defineAMState) {
        this.defineAMState = defineAMState;
    }

}
